from sqlalchemy.orm import Session
from .stu_models import Stu  # 导入学生模型类
from .stu_schema import Stu_schema  # 导入学生数据验证模型
from sqlalchemy import func  # 导入SQL函数工具



# 学生基本信息表CRUD操作

# 查询所有学生信息
def get_all_stu(db: Session):
    """查询数据库中所有学生的完整信息"""
    return db.query(Stu).all()

# 通过学生ID查询
def get_id_stu(db: Session, student_id: int):
    """
    通过学生编号查询单个学生信息
    :param db: 数据库会话对象
    :param student_id: 学生编号
    :return: 匹配的学生对象或None
    """
    return db.query(Stu).filter(Stu.student_id == student_id).first()

# 通过姓名查询学生（支持同名学生）
def get_name_stu(db: Session, student_name: str):
    """通过姓名查询学生，返回所有同名学生列表"""
    return db.query(Stu).filter(Stu.student_name == student_name)

# 通过班级查询学生
def get_class_stu(db: Session, class_name: str):
    """查询指定班级的所有学生"""
    return db.query(Stu).filter(Stu.class_name == class_name)

# 添加新学生
def add_stu(db: Session, stu_schema: Stu_schema):
    """
    添加新学生信息到数据库
    :param db: 数据库会话
    :param stu_schema: 经过验证的学生数据模型
    :return: 新增的学生记录（含数据库生成的字段）
    """
    # 将Pydantic模型转换为字典，创建数据库模型对象
    db_stu = Stu(**stu_schema.dict())
    db.add(db_stu)  # 添加到会话
    db.commit()  # 提交事务
    db.refresh(db_stu)  # 刷新对象，获取数据库生成的属性
    return db_stu

# 修改学生信息
def mod_stu(db: Session, mod_schema: Stu_schema):
    """
    修改学生信息，仅更新提供的非空字段
    :param db: 数据库会话
    :param mod_schema: 包含更新信息的模型（必须包含student_id）
    :return: 更新后的学生对象或None（若学生不存在）
    """
    # 获取要修改的学生查询对象
    db_stu = db.query(Stu).filter(Stu.student_id == mod_schema.student_id)
    if not db_stu.first():  # 检查学生是否存在
        return None
    # 只更新非空字段（排除未设置的字段）
    update_data = mod_schema.dict(exclude_unset=True)
    db_stu.update(update_data)  # 执行更新
    db.commit()  # 提交事务
    return db_stu.first()  # 返回更新后的对象

# 多条件筛选查询学生
def get_stu_by_filters(db: Session, student_id: int = None, student_name: str = None, class_name: int = None):
    """
    支持多条件组合查询学生信息
    :param db: 数据库会话
    :param student_id: 学生编号（可选）
    :param student_name: 学生姓名（可选）
    :param class_name: 班级名称（可选）
    :return: 符合条件的学生列表
    """
    query = db.query(Stu)  # 基础查询对象
    # 动态添加筛选条件
    if student_id:
        query = query.filter(Stu.student_id == student_id)
    if student_name:
        query = query.filter(Stu.student_name == student_name)
    if class_name:
        query = query.filter(Stu.class_name == class_name)
    return query.all()

# 查询所有超过30岁的学员信息
def get_stu_over_30(db: Session):
    """查询年龄大于30岁的所有学生信息"""
    return db.query(Stu).filter(Stu.age > 30).all()

# 统计每个班级的男女生人数
def count_gender_by_class(db: Session):
    """
    按班级和性别分组统计人数
    :return: 包含班级、性别、人数的字典列表
    """
    result = db.query(
        Stu.class_name,  # 分组字段1：班级
        Stu.gender,      # 分组字段2：性别
        func.count(Stu.student_id).label("count")  # 统计人数并命名为count
    ).group_by(Stu.class_name, Stu.gender).all()  # 按两个字段分组
    # 转换为可读性更高的字典格式
    return [{"班级": c, "性别": g, "人数": cnt} for c, g, cnt in result]